﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using NXT2Adapter;
using System.Diagnostics;

namespace Kinixt
{
    /// <summary>
    /// Interaction logic for Menu.xaml
    /// </summary>
    public partial class Menu : Window
    {
        #region Fields and constants

        /// <summary>
        /// The window will be wider by this ammount when debug console is expanded.
        /// </summary>
        private const double EXPAND_SIZE = 775;

        // The text that can be displayed on Start button in different situations.
        private const string START_TEXT = "Start";
        private const string RESUME_TEXT = "Resume";

        private HUD hudWindow = null;

        #endregion

        public Menu()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Switches from HUD to menu window.
        /// </summary>
        /// <param name="closeHUD">If true, then will destroy HUD window.</param>
        public void SwitchTo(bool closeHUD)
        {
            App.Current.MainWindow = this;           
            hudWindow.Hide();
            this.Show();

            if (closeHUD)
            {
                InactiveMode();
                DestroyHUD();
            }
        }

        #region Private utility methods

        /// <summary>
        /// Releases all resources of the program.
        /// </summary>
        private void DestroyMenu()
        {
            if (hudWindow != null)
            {
                DestroyHUD();
            }
        }

        /// <summary>
        /// Destroys the HUD window, closes any connections and releases all resources. 
        /// </summary>
        private void DestroyHUD()
        {
            hudWindow.Destroy();
            hudWindow.Close();
            hudWindow = null;
            InactiveMode();
        }

        /// <summary>
        /// Switches the state of menu controls for when the HUD is created.
        /// </summary>
        private void ActiveMode()
        {
            startButton.Content = RESUME_TEXT;
            stopButton.IsEnabled = true;
            steeringMethodCombobox.IsEnabled = false;
            steeredObjectComboBox.IsEnabled = false;
            kinectPreviewCheckBox.IsEnabled = false;
            transmitterIPTextBox.IsEnabled = false;
        }

        /// <summary>
        /// Switches the state of menu controls for when there is no HUD created.
        /// </summary>
        private void InactiveMode()
        {
            startButton.Content = START_TEXT;
            stopButton.IsEnabled = false;
            steeringMethodCombobox.IsEnabled = true;
            steeredObjectComboBox.IsEnabled = true;
            kinectPreviewCheckBox.IsEnabled = true;
            transmitterIPTextBox.IsEnabled = true;
        }

        #endregion

        #region Event handling

        /// <summary>
        /// Expands menu window to accomodate expanded debug console.
        /// </summary>
        private void debugExpander_Expanded(object sender, RoutedEventArgs e)
        {
            this.Width += EXPAND_SIZE;
        }

        /// <summary>
        /// Contracts menu window because the debug console collapses.
        /// </summary>
        private void debugExpander_Collapsed(object sender, RoutedEventArgs e)
        {
            this.Width -= EXPAND_SIZE;
        }

        /// <summary>
        /// Creates the HUD or makes it visible again if it is already created.
        /// </summary>
        private void StartHUD(object sender, RoutedEventArgs e)
        {
            if (validateComPort() == false)
            {
                return;
            }

            if (hudWindow == null)  // creating and switching to HUD window
            {
                string adapterName = ((ComboBoxItem)steeringMethodCombobox.SelectedItem).Content.ToString();
                string controlName = ((ComboBoxItem)steeredObjectComboBox.SelectedItem).Content.ToString();
                string transmitterIP = transmitterIPTextBox.Text;
                bool isPrevievSelected = (bool)kinectPreviewCheckBox.IsChecked;

                byte comPort = (byte)0;
                if (this.comPortTextBox.Text != "")
                {
                    comPort = (byte)this.comPortTextBox.Text[0]; // we know it becouse comPortTextBox.maxLength is one
                }

                //hudWindow.SwitchTo();
                ActiveMode();

                hudWindow = new HUD(this, adapterName, controlName, transmitterIP, isPrevievSelected, comPort);            
            }
            
            hudWindow.Start();
        }

        private bool validateComPort()
        {
            if (comPortTextBox.Visibility != System.Windows.Visibility.Visible)
            {
                return true;
            }

            // TODO : przydał by się jakiś system powiadamiania użytkownika o błędach
            SolidColorBrush solidColorBrush = new SolidColorBrush();

            if (comPortTextBox.Text == "")
            {
                Debug.WriteLine("no com port typed");
                solidColorBrush.Color = Colors.Red;
                comPortLabel.Foreground = solidColorBrush;               
                return false;

            }


            int comPortAsInt;
            bool result = int.TryParse(comPortTextBox.Text, out comPortAsInt);

            if (result == false)
            {
                Debug.WriteLine("not only digits typed");
                solidColorBrush.Color = Colors.Red;
                comPortLabel.Foreground = solidColorBrush;
                return false;
            }

            solidColorBrush.Color = Colors.Black;
            comPortLabel.Foreground = solidColorBrush;
            return true;           
        }

        private void stopButton_Click(object sender, RoutedEventArgs e)
        {
            DestroyHUD();
        }

        private void exitButton_Click(object sender, RoutedEventArgs e)
        {
            DestroyMenu();
            this.Close();
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            DestroyMenu();
        }

        #endregion

        private void steeredObjectComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count == 1)
            {
                ComboBoxItem selectedItem = (ComboBoxItem)e.AddedItems[0];
                if (selectedItem.Content.Equals("Simulation"))
                {
                    comPortLabel.Visibility = System.Windows.Visibility.Collapsed;
                    comPortTextBox.Visibility = System.Windows.Visibility.Collapsed;
                }
                else
                {
                    if (comPortLabel != null)
                    {
                        comPortLabel.Visibility = System.Windows.Visibility.Visible;
                    }
                    if (comPortTextBox != null)
                    {
                        comPortTextBox.Visibility = System.Windows.Visibility.Visible;
                    }
                }
            }
            else 
            {
                Debug.WriteLine("WTF?!? more or less then one item selected");
            }
        }
    }
}
